﻿using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

using Noris.Schedule.Support;
using Noris.Schedule.Support.Core;
using Noris.Schedule.Support.Services;

namespace Noris.Schedule.UI.Components
{
	// POKRAČOVÁNÍ TŘÍDY GridGraphCls : KRESLENÍ ELEMENTŮ
	/// <summary>
	/// Třída pro zobrazování grafu některého typu v rámci gridu
	/// </summary>
	internal partial class GridGraphCls : DblGraphControl, ILeaveFocus
	{
		/// <summary>
		/// Vstupní metoda pro kreslení libovolného elementu.
		/// </summary>
		/// <param name="elementKey"></param>
		/// <param name="args"></param>
		private void _PaintRowGraphElement(GraphElementPainterKey elementKey, GraphElementPainterArgs args)
		{
			// Kreslení pomocí specializovaného painteru:
			IGraphElementPainter painter = this._GridPainter.GetPainter(elementKey);
			if (painter != null)
			{
				painter.Paint(args);
				if (!args.IsAllFinished)
					this._PaintElementDefault(args);
				if (args.CallPaintAfter)
					painter.PaintAfter(args);
				return;
			}

			// Vykreslím místo s problémem (nikdo z painterů se neujal kreslení):
			args.PaintArgs.Graphics.FillRectangle(SystemBrushes.ButtonFace, args.ElementArea);
			args.PaintArgs.Graphics.DrawString("ERROR", SystemFonts.SmallCaptionFont, SystemBrushes.ControlText, args.ElementArea);
		}
		// Ke zrušení, začátek:
		#region SKUPINOVÉ DETEKTORY POLOŽEK (GRAFICKÉ NÁSTROJE PRO KRESLENÍ ELEMENTŮ GRAFU) A KONVERTORY NA SKUPINOVÉ ENUMY
		/// <summary>
		/// Detekuje, zda zadaný typ palety je paletou grafického elementu pro graf typu Gantt.
		/// </summary>
		/// <param name="paletteType"></param>
		/// <returns></returns>
		private bool _PaletteIsGraphGantt(GridGraphPaletteType paletteType)
		{
			switch (paletteType)
			{
				case GridGraphPaletteType.GraphGantt1_Standard:
				case GridGraphPaletteType.GraphGantt1_Fixed:
				case GridGraphPaletteType.GraphGantt1_MouseOn:
				case GridGraphPaletteType.GraphGantt1_Active:
				case GridGraphPaletteType.GraphGantt1_Selected:

				case GridGraphPaletteType.GraphGantt2_Standard:
				case GridGraphPaletteType.GraphGantt2_Fixed:
				case GridGraphPaletteType.GraphGantt2_MouseOn:
				case GridGraphPaletteType.GraphGantt2_Active:
				case GridGraphPaletteType.GraphGantt2_Selected:

				case GridGraphPaletteType.GraphGantt3_Standard:
				case GridGraphPaletteType.GraphGantt3_Fixed:
				case GridGraphPaletteType.GraphGantt3_MouseOn:
				case GridGraphPaletteType.GraphGantt3_Active:
				case GridGraphPaletteType.GraphGantt3_Selected:

				case GridGraphPaletteType.GraphGantt4_Standard:
				case GridGraphPaletteType.GraphGantt4_Fixed:
				case GridGraphPaletteType.GraphGantt4_MouseOn:
				case GridGraphPaletteType.GraphGantt4_Active:
				case GridGraphPaletteType.GraphGantt4_Selected:

				case GridGraphPaletteType.GraphGantt5_Standard:
				case GridGraphPaletteType.GraphGantt5_Fixed:
				case GridGraphPaletteType.GraphGantt5_MouseOn:
				case GridGraphPaletteType.GraphGantt5_Active:
				case GridGraphPaletteType.GraphGantt5_Selected:

				case GridGraphPaletteType.GraphGantt6_Standard:
				case GridGraphPaletteType.GraphGantt6_Fixed:
				case GridGraphPaletteType.GraphGantt6_MouseOn:
				case GridGraphPaletteType.GraphGantt6_Active:
				case GridGraphPaletteType.GraphGantt6_Selected:

				case GridGraphPaletteType.GraphGantt7_Standard:
				case GridGraphPaletteType.GraphGantt7_Fixed:
				case GridGraphPaletteType.GraphGantt7_MouseOn:
				case GridGraphPaletteType.GraphGantt7_Active:
				case GridGraphPaletteType.GraphGantt7_Selected:

				case GridGraphPaletteType.GraphGantt8_Standard:
				case GridGraphPaletteType.GraphGantt8_Fixed:
				case GridGraphPaletteType.GraphGantt8_MouseOn:
				case GridGraphPaletteType.GraphGantt8_Active:
				case GridGraphPaletteType.GraphGantt8_Selected:

				case GridGraphPaletteType.GraphGantt9_Standard:
				case GridGraphPaletteType.GraphGantt9_Fixed:
				case GridGraphPaletteType.GraphGantt9_MouseOn:
				case GridGraphPaletteType.GraphGantt9_Active:
				case GridGraphPaletteType.GraphGantt9_Selected:
					return true;
			}
			return false;
		}
		/// <summary>
		/// Detekuje, zda zadaný typ palety je paletou grafického elementu pro graf typu Capacity.
		/// </summary>
		/// <param name="paletteType"></param>
		/// <returns></returns>
		private bool _PaletteIsGraphCapacityFrame(GridGraphPaletteType paletteType)
		{
			switch (paletteType)
			{
				case GridGraphPaletteType.CapacityFrame1:
				case GridGraphPaletteType.CapacityFrame2:
				case GridGraphPaletteType.CapacityFrame3:
				case GridGraphPaletteType.CapacityFrame4:
				case GridGraphPaletteType.CapacityFrame5:
				case GridGraphPaletteType.CapacityFrame6:
				case GridGraphPaletteType.CapacityFrame7:
				case GridGraphPaletteType.CapacityFrame8:
				case GridGraphPaletteType.CapacityFrame9:
					return true;
			}
			return false;
		}
		/// <summary>
		/// Detekuje, zda zadaný typ palety je paletou grafického elementu pro graf typu Link.
		/// </summary>
		/// <param name="paletteType"></param>
		/// <returns></returns>
		private bool _PaletteIsGraphLink(GridGraphPaletteType paletteType)
		{
			switch (paletteType)
			{
				case GridGraphPaletteType.GraphLink1_Standard:
				case GridGraphPaletteType.GraphLink1_Fixed:
				case GridGraphPaletteType.GraphLink1_MouseOn:
				case GridGraphPaletteType.GraphLink1_Active:
				case GridGraphPaletteType.GraphLink1_Selected:

				case GridGraphPaletteType.GraphLink2_Standard:
				case GridGraphPaletteType.GraphLink2_Fixed:
				case GridGraphPaletteType.GraphLink2_MouseOn:
				case GridGraphPaletteType.GraphLink2_Active:
				case GridGraphPaletteType.GraphLink2_Selected:

				case GridGraphPaletteType.GraphLink3_Standard:
				case GridGraphPaletteType.GraphLink3_Fixed:
				case GridGraphPaletteType.GraphLink3_MouseOn:
				case GridGraphPaletteType.GraphLink3_Active:
				case GridGraphPaletteType.GraphLink3_Selected:

				case GridGraphPaletteType.GraphLink4_Standard:
				case GridGraphPaletteType.GraphLink4_Fixed:
				case GridGraphPaletteType.GraphLink4_MouseOn:
				case GridGraphPaletteType.GraphLink4_Active:
				case GridGraphPaletteType.GraphLink4_Selected:

				case GridGraphPaletteType.GraphLink5_Standard:
				case GridGraphPaletteType.GraphLink5_Fixed:
				case GridGraphPaletteType.GraphLink5_MouseOn:
				case GridGraphPaletteType.GraphLink5_Active:
				case GridGraphPaletteType.GraphLink5_Selected:

				case GridGraphPaletteType.GraphLink6_Standard:
				case GridGraphPaletteType.GraphLink6_Fixed:
				case GridGraphPaletteType.GraphLink6_MouseOn:
				case GridGraphPaletteType.GraphLink6_Active:
				case GridGraphPaletteType.GraphLink6_Selected:

				case GridGraphPaletteType.GraphLink7_Standard:
				case GridGraphPaletteType.GraphLink7_Fixed:
				case GridGraphPaletteType.GraphLink7_MouseOn:
				case GridGraphPaletteType.GraphLink7_Active:
				case GridGraphPaletteType.GraphLink7_Selected:

				case GridGraphPaletteType.GraphLink8_Standard:
				case GridGraphPaletteType.GraphLink8_Fixed:
				case GridGraphPaletteType.GraphLink8_MouseOn:
				case GridGraphPaletteType.GraphLink8_Active:
				case GridGraphPaletteType.GraphLink8_Selected:

				case GridGraphPaletteType.GraphLink9_Standard:
				case GridGraphPaletteType.GraphLink9_Fixed:
				case GridGraphPaletteType.GraphLink9_MouseOn:
				case GridGraphPaletteType.GraphLink9_Active:
				case GridGraphPaletteType.GraphLink9_Selected:
					return true;
			}
			return false;
		}
		/// <summary>
		/// Vrátí typ gradientu pro danou paletu.
		/// Metoda je použitelná pro grafy typu Gantt i Link.
		/// </summary>
		/// <param name="paletteType"></param>
		/// <returns></returns>
		private _GraphElementGradientType _PaletteGetGradient(GridGraphPaletteType paletteType)
		{
			switch (paletteType)
			{
				case GridGraphPaletteType.GraphGantt1_Standard:
				case GridGraphPaletteType.GraphGantt2_Standard:
				case GridGraphPaletteType.GraphGantt3_Standard:
				case GridGraphPaletteType.GraphGantt4_Standard:
				case GridGraphPaletteType.GraphGantt5_Standard:
				case GridGraphPaletteType.GraphGantt6_Standard:
				case GridGraphPaletteType.GraphGantt7_Standard:
				case GridGraphPaletteType.GraphGantt8_Standard:
				case GridGraphPaletteType.GraphGantt9_Standard:
				case GridGraphPaletteType.GraphLink1_Standard:
				case GridGraphPaletteType.GraphLink2_Standard:
				case GridGraphPaletteType.GraphLink3_Standard:
				case GridGraphPaletteType.GraphLink4_Standard:
				case GridGraphPaletteType.GraphLink5_Standard:
				case GridGraphPaletteType.GraphLink6_Standard:
				case GridGraphPaletteType.GraphLink7_Standard:
				case GridGraphPaletteType.GraphLink8_Standard:
				case GridGraphPaletteType.GraphLink9_Standard:
					return _GraphElementGradientType.Standard;

				case GridGraphPaletteType.GraphGantt1_Fixed:
				case GridGraphPaletteType.GraphGantt2_Fixed:
				case GridGraphPaletteType.GraphGantt3_Fixed:
				case GridGraphPaletteType.GraphGantt4_Fixed:
				case GridGraphPaletteType.GraphGantt5_Fixed:
				case GridGraphPaletteType.GraphGantt6_Fixed:
				case GridGraphPaletteType.GraphGantt7_Fixed:
				case GridGraphPaletteType.GraphGantt8_Fixed:
				case GridGraphPaletteType.GraphGantt9_Fixed:
				case GridGraphPaletteType.GraphLink1_Fixed:
				case GridGraphPaletteType.GraphLink2_Fixed:
				case GridGraphPaletteType.GraphLink3_Fixed:
				case GridGraphPaletteType.GraphLink4_Fixed:
				case GridGraphPaletteType.GraphLink5_Fixed:
				case GridGraphPaletteType.GraphLink6_Fixed:
				case GridGraphPaletteType.GraphLink7_Fixed:
				case GridGraphPaletteType.GraphLink8_Fixed:
				case GridGraphPaletteType.GraphLink9_Fixed:
					return _GraphElementGradientType.Fixed;

				case GridGraphPaletteType.GraphGantt1_MouseOn:
				case GridGraphPaletteType.GraphGantt2_MouseOn:
				case GridGraphPaletteType.GraphGantt3_MouseOn:
				case GridGraphPaletteType.GraphGantt4_MouseOn:
				case GridGraphPaletteType.GraphGantt5_MouseOn:
				case GridGraphPaletteType.GraphGantt6_MouseOn:
				case GridGraphPaletteType.GraphGantt7_MouseOn:
				case GridGraphPaletteType.GraphGantt8_MouseOn:
				case GridGraphPaletteType.GraphGantt9_MouseOn:
				case GridGraphPaletteType.GraphLink1_MouseOn:
				case GridGraphPaletteType.GraphLink2_MouseOn:
				case GridGraphPaletteType.GraphLink3_MouseOn:
				case GridGraphPaletteType.GraphLink4_MouseOn:
				case GridGraphPaletteType.GraphLink5_MouseOn:
				case GridGraphPaletteType.GraphLink6_MouseOn:
				case GridGraphPaletteType.GraphLink7_MouseOn:
				case GridGraphPaletteType.GraphLink8_MouseOn:
				case GridGraphPaletteType.GraphLink9_MouseOn:
					return _GraphElementGradientType.OnMouse;

				case GridGraphPaletteType.GraphGantt1_Active:
				case GridGraphPaletteType.GraphGantt2_Active:
				case GridGraphPaletteType.GraphGantt3_Active:
				case GridGraphPaletteType.GraphGantt4_Active:
				case GridGraphPaletteType.GraphGantt5_Active:
				case GridGraphPaletteType.GraphGantt6_Active:
				case GridGraphPaletteType.GraphGantt7_Active:
				case GridGraphPaletteType.GraphGantt8_Active:
				case GridGraphPaletteType.GraphGantt9_Active:
				case GridGraphPaletteType.GraphLink1_Active:
				case GridGraphPaletteType.GraphLink2_Active:
				case GridGraphPaletteType.GraphLink3_Active:
				case GridGraphPaletteType.GraphLink4_Active:
				case GridGraphPaletteType.GraphLink5_Active:
				case GridGraphPaletteType.GraphLink6_Active:
				case GridGraphPaletteType.GraphLink7_Active:
				case GridGraphPaletteType.GraphLink8_Active:
				case GridGraphPaletteType.GraphLink9_Active:
					return _GraphElementGradientType.Active;

				case GridGraphPaletteType.GraphGantt1_Selected:
				case GridGraphPaletteType.GraphGantt2_Selected:
				case GridGraphPaletteType.GraphGantt3_Selected:
				case GridGraphPaletteType.GraphGantt4_Selected:
				case GridGraphPaletteType.GraphGantt5_Selected:
				case GridGraphPaletteType.GraphGantt6_Selected:
				case GridGraphPaletteType.GraphGantt7_Selected:
				case GridGraphPaletteType.GraphGantt8_Selected:
				case GridGraphPaletteType.GraphGantt9_Selected:
				case GridGraphPaletteType.GraphLink1_Selected:
				case GridGraphPaletteType.GraphLink2_Selected:
				case GridGraphPaletteType.GraphLink3_Selected:
				case GridGraphPaletteType.GraphLink4_Selected:
				case GridGraphPaletteType.GraphLink5_Selected:
				case GridGraphPaletteType.GraphLink6_Selected:
				case GridGraphPaletteType.GraphLink7_Selected:
				case GridGraphPaletteType.GraphLink8_Selected:
				case GridGraphPaletteType.GraphLink9_Selected:
					return _GraphElementGradientType.Selected;
			}
			return _GraphElementGradientType.Standard;
		}
		/// <summary>
		/// Vrátí vizuální typ elementu pro danou paletu (číslo skinu).
		/// Metoda je použitelná pro grafy typu Gantt, Capacity i Link.
		/// </summary>
		/// <param name="paletteType"></param>
		/// <returns></returns>
		private GraphElementVisualType _PaletteGetVisualType(GridGraphPaletteType paletteType)
		{
			switch (paletteType)
			{
				case GridGraphPaletteType.GraphGantt1_Standard:
				case GridGraphPaletteType.GraphGantt1_Fixed:
				case GridGraphPaletteType.GraphGantt1_MouseOn:
				case GridGraphPaletteType.GraphGantt1_Active:
				case GridGraphPaletteType.GraphGantt1_Selected:
				case GridGraphPaletteType.CapacityFrame1:
				case GridGraphPaletteType.GraphLink1_Standard:
				case GridGraphPaletteType.GraphLink1_Fixed:
				case GridGraphPaletteType.GraphLink1_MouseOn:
				case GridGraphPaletteType.GraphLink1_Active:
				case GridGraphPaletteType.GraphLink1_Selected:
					return GraphElementVisualType.Type1;

				case GridGraphPaletteType.GraphGantt2_Standard:
				case GridGraphPaletteType.GraphGantt2_Fixed:
				case GridGraphPaletteType.GraphGantt2_MouseOn:
				case GridGraphPaletteType.GraphGantt2_Active:
				case GridGraphPaletteType.GraphGantt2_Selected:
				case GridGraphPaletteType.CapacityFrame2:
				case GridGraphPaletteType.GraphLink2_Standard:
				case GridGraphPaletteType.GraphLink2_Fixed:
				case GridGraphPaletteType.GraphLink2_MouseOn:
				case GridGraphPaletteType.GraphLink2_Active:
				case GridGraphPaletteType.GraphLink2_Selected:
					return GraphElementVisualType.Type2;

				case GridGraphPaletteType.GraphGantt3_Standard:
				case GridGraphPaletteType.GraphGantt3_Fixed:
				case GridGraphPaletteType.GraphGantt3_MouseOn:
				case GridGraphPaletteType.GraphGantt3_Active:
				case GridGraphPaletteType.GraphGantt3_Selected:
				case GridGraphPaletteType.CapacityFrame3:
				case GridGraphPaletteType.GraphLink3_Standard:
				case GridGraphPaletteType.GraphLink3_Fixed:
				case GridGraphPaletteType.GraphLink3_MouseOn:
				case GridGraphPaletteType.GraphLink3_Active:
				case GridGraphPaletteType.GraphLink3_Selected:
					return GraphElementVisualType.Type3;

				case GridGraphPaletteType.GraphGantt4_Standard:
				case GridGraphPaletteType.GraphGantt4_Fixed:
				case GridGraphPaletteType.GraphGantt4_MouseOn:
				case GridGraphPaletteType.GraphGantt4_Active:
				case GridGraphPaletteType.GraphGantt4_Selected:
				case GridGraphPaletteType.CapacityFrame4:
				case GridGraphPaletteType.GraphLink4_Standard:
				case GridGraphPaletteType.GraphLink4_Fixed:
				case GridGraphPaletteType.GraphLink4_MouseOn:
				case GridGraphPaletteType.GraphLink4_Active:
				case GridGraphPaletteType.GraphLink4_Selected:
					return GraphElementVisualType.Type4;

				case GridGraphPaletteType.GraphGantt5_Standard:
				case GridGraphPaletteType.GraphGantt5_Fixed:
				case GridGraphPaletteType.GraphGantt5_MouseOn:
				case GridGraphPaletteType.GraphGantt5_Active:
				case GridGraphPaletteType.GraphGantt5_Selected:
				case GridGraphPaletteType.CapacityFrame5:
				case GridGraphPaletteType.GraphLink5_Standard:
				case GridGraphPaletteType.GraphLink5_Fixed:
				case GridGraphPaletteType.GraphLink5_MouseOn:
				case GridGraphPaletteType.GraphLink5_Active:
				case GridGraphPaletteType.GraphLink5_Selected:
					return GraphElementVisualType.Type5;

				case GridGraphPaletteType.GraphGantt6_Standard:
				case GridGraphPaletteType.GraphGantt6_Fixed:
				case GridGraphPaletteType.GraphGantt6_MouseOn:
				case GridGraphPaletteType.GraphGantt6_Active:
				case GridGraphPaletteType.GraphGantt6_Selected:
				case GridGraphPaletteType.CapacityFrame6:
				case GridGraphPaletteType.GraphLink6_Standard:
				case GridGraphPaletteType.GraphLink6_Fixed:
				case GridGraphPaletteType.GraphLink6_MouseOn:
				case GridGraphPaletteType.GraphLink6_Active:
				case GridGraphPaletteType.GraphLink6_Selected:
					return GraphElementVisualType.Type6;

				case GridGraphPaletteType.GraphGantt7_Standard:
				case GridGraphPaletteType.GraphGantt7_Fixed:
				case GridGraphPaletteType.GraphGantt7_MouseOn:
				case GridGraphPaletteType.GraphGantt7_Active:
				case GridGraphPaletteType.GraphGantt7_Selected:
				case GridGraphPaletteType.CapacityFrame7:
				case GridGraphPaletteType.GraphLink7_Standard:
				case GridGraphPaletteType.GraphLink7_Fixed:
				case GridGraphPaletteType.GraphLink7_MouseOn:
				case GridGraphPaletteType.GraphLink7_Active:
				case GridGraphPaletteType.GraphLink7_Selected:
					return GraphElementVisualType.Type7;

				case GridGraphPaletteType.GraphGantt8_Standard:
				case GridGraphPaletteType.GraphGantt8_Fixed:
				case GridGraphPaletteType.GraphGantt8_MouseOn:
				case GridGraphPaletteType.GraphGantt8_Active:
				case GridGraphPaletteType.GraphGantt8_Selected:
				case GridGraphPaletteType.CapacityFrame8:
				case GridGraphPaletteType.GraphLink8_Standard:
				case GridGraphPaletteType.GraphLink8_Fixed:
				case GridGraphPaletteType.GraphLink8_MouseOn:
				case GridGraphPaletteType.GraphLink8_Active:
				case GridGraphPaletteType.GraphLink8_Selected:
					return GraphElementVisualType.Type8;

				case GridGraphPaletteType.GraphGantt9_Standard:
				case GridGraphPaletteType.GraphGantt9_Fixed:
				case GridGraphPaletteType.GraphGantt9_MouseOn:
				case GridGraphPaletteType.GraphGantt9_Active:
				case GridGraphPaletteType.GraphGantt9_Selected:
				case GridGraphPaletteType.CapacityFrame9:
				case GridGraphPaletteType.GraphLink9_Standard:
				case GridGraphPaletteType.GraphLink9_Fixed:
				case GridGraphPaletteType.GraphLink9_MouseOn:
				case GridGraphPaletteType.GraphLink9_Active:
				case GridGraphPaletteType.GraphLink9_Selected:
					return GraphElementVisualType.Type9;
			}
			return GraphElementVisualType.Type1;
		}
		#endregion
		#region STARÉ GENERÁTORY BRUSH
		/// <summary>
		/// Metoda, která vytváří na požádání grafický prvek Brush, varianta pro element Graf Gantt.
		/// </summary>
		/// <param name="paletteType">Typ požadovaného fontu</param>
		/// <param name="rectangle">Vstupní informace o tom, v kterém prostoru bude nástroj použit. Pro některé Brush (např. LinearGradient) je to důležité.</param>
		/// <param name="repeatType">Out informace o typu opakování motivu Brushe</param>
		/// <returns>Požadovaný Brush. Pokud bude vráceno null, pak se null vrátí do aplikace namísto Brush.</returns>
		internal virtual Brush PaletteCreateBrushGraphGantt(GridGraphPaletteType paletteType, Rectangle rectangle, out GraphicsPaletteBrushRepeatType repeatType)
		{
			_GraphElementGradientType gradient = _PaletteGetGradient(paletteType);
			GraphElementVisualType visual = _PaletteGetVisualType(paletteType);
			Color color = this._GridData.GetColorForElement(RowGraphMode.Gantt, visual);
			return this._PaletteCreateBrushElementGraphGantt(rectangle, color, gradient, out repeatType);
		}
		/// <summary>
		/// Metoda, která vytváří na požádání grafický prvek Brush, varianta pro element Graf Capacity.
		/// </summary>
		/// <param name="paletteType">Typ požadovaného fontu</param>
		/// <param name="rectangle">Vstupní informace o tom, v kterém prostoru bude nástroj použit. Pro některé Brush (např. LinearGradient) je to důležité.</param>
		/// <param name="repeatType">Out informace o typu opakování motivu Brushe</param>
		/// <returns>Požadovaný Brush. Pokud bude vráceno null, pak se null vrátí do aplikace namísto Brush.</returns>
		internal virtual Brush PaletteCreateBrushGraphCapacity(GridGraphPaletteType paletteType, Rectangle rectangle, out GraphicsPaletteBrushRepeatType repeatType)
		{
			repeatType = GraphicsPaletteBrushRepeatType.None;
			GraphElementVisualType visual = _PaletteGetVisualType(paletteType);
			Color color = this._GridData.GetColorForElement(RowGraphMode.CapacityUtilization, visual);
			return new SolidBrush(color);
		}
		/// <summary>
		/// Metoda, která vytváří na požádání grafický prvek Brush, varianta pro element Graf Link.
		/// </summary>
		/// <param name="paletteType">Typ požadovaného fontu</param>
		/// <param name="rectangle">Vstupní informace o tom, v kterém prostoru bude nástroj použit. Pro některé Brush (např. LinearGradient) je to důležité.</param>
		/// <param name="repeatType">Out informace o typu opakování motivu Brushe</param>
		/// <returns>Požadovaný Brush. Pokud bude vráceno null, pak se null vrátí do aplikace namísto Brush.</returns>
		internal virtual Brush PaletteCreateBrushGraphLink(GridGraphPaletteType paletteType, Rectangle rectangle, out GraphicsPaletteBrushRepeatType repeatType)
		{
			_GraphElementGradientType gradient = _PaletteGetGradient(paletteType);
			GraphElementVisualType visual = _PaletteGetVisualType(paletteType);
			Color color = this._GridData.GetColorForElement(RowGraphMode.TaskCapacityLink, visual);
			return this._PaletteCreateBrushElementGraphLink(rectangle, color, gradient, out repeatType);
		}
		/// <summary>
		/// Vygeneruje Brush pro element grafu, typu Gantt, podle konstantní logiky, s proměnným zadáním barev a modifikátorů
		/// </summary>
		/// <param name="area">Prostor, pro který se má gradient vypočítat. 
		/// Gradient může být prostorově závislý (pak musí svoji prostorovou závislost vyplnit do out parametru repeatType).</param>
		/// <param name="color">Základní barva, je daná skinem pro daný vizuální typ položky, odvozeno z Aps.DataElementCls.ElementVisualType</param>
		/// <param name="gradientType">Typ gradientu = odpovídá modifikaci palety = aktuální stav elementu (běžný, pod myší, fixní, aktivně pohybovaný, selectovaný)</param>
		/// <param name="repeatType">Out informace o prostorové závislosti gradientu. Pokud bude gradient příště použit pro odpovídající prostor, nebude se opakovaně generovat.</param>
		/// <returns>Brush pro danou situaci</returns>
		private Brush _PaletteCreateBrushElementGraphGantt(Rectangle area, Color color, _GraphElementGradientType gradientType, out GraphicsPaletteBrushRepeatType repeatType)
		{
			repeatType = GraphicsPaletteBrushRepeatType.Horizontal;
			Color basicColor = color;        // Základní barva, střed objektu
			Color lightColor = basicColor;   // Světlejší barva, většinou bývá nahoře (kromě stavu _GraphElementGradientType.ActiveItemBack)
			Color darkColor = basicColor;    // Tmavší barva, většinou je dole
			Color mediumColor;
			Color edgeColor = basicColor;    // Přechodová barva, jen v ActiveItemBack gradientu

			LinearGradientBrush lgb = new LinearGradientBrush(area, Color.LightGray, Color.Gray, 90F);
			ColorBlend cbl;
			HatchBrush htb;
			switch (gradientType)
			{
				case _GraphElementGradientType.Standard:
					// Standardní gradient
					basicColor = color;
					darkColor = ComponentLibrary.ColorShift(basicColor, -48);
					lightColor = ComponentLibrary.ColorShift(basicColor, 64);
					cbl = new ColorBlend(6);
					cbl.Positions = ComponentLibrary.GetColorBlendPosition(area.Height, new int[] { 0, 1, 5, -6, -2, 0 });
					cbl.Colors = new Color[] { lightColor, lightColor, basicColor, basicColor, darkColor, darkColor };
					lgb.InterpolationColors = cbl;
					return lgb;
				case _GraphElementGradientType.Fixed:
					// Conservative gradient
					repeatType = GraphicsPaletteBrushRepeatType.None;
					basicColor = ComponentLibrary.ColorShift(color, +64);
					darkColor = ComponentLibrary.ColorShift(color, -32);
					htb = new HatchBrush(HatchStyle.SmallCheckerBoard, basicColor, darkColor);
					return htb;
				case _GraphElementGradientType.OnMouse:
					// OnMouse gradient
					basicColor = ComponentLibrary.ColorShift(color, 16, 32, 32);
					darkColor = ComponentLibrary.ColorShift(basicColor, -48);
					lightColor = ComponentLibrary.ColorShift(basicColor, 32, 64, 64);
					cbl = new ColorBlend(6);
					cbl.Positions = ComponentLibrary.GetColorBlendPosition(area.Height, new int[] { 0, 1, 7, -8, -2, 0 });
					cbl.Colors = new Color[] { lightColor, lightColor, basicColor, basicColor, darkColor, darkColor };
					lgb.InterpolationColors = cbl;
					return lgb;
				case _GraphElementGradientType.Selected:
					// Selected gradient
					repeatType = GraphicsPaletteBrushRepeatType.None;
					basicColor = ComponentLibrary.ColorShift(color, +96);
					darkColor = ComponentLibrary.ColorShift(color, +16);
					htb = new HatchBrush(HatchStyle.DarkHorizontal, basicColor, darkColor);
					return htb;
				case _GraphElementGradientType.Active:
					// Aktivní gradient: má opačné pořadí barev (nahoře tmavý, dole světlý), čímž reprezentuje "dolů promáčknutý" stav:
					basicColor = ComponentLibrary.ColorShift(color, +16);
					basicColor = ComponentLibrary.ColorShift(color, 16, 64, 64);
					mediumColor = ComponentLibrary.ColorShift(color, -24);
					darkColor = ComponentLibrary.ColorShift(basicColor, -48);
					lightColor = ComponentLibrary.ColorShift(basicColor, 64, 48, 64);
					cbl = new ColorBlend(8);
					cbl.Positions = ComponentLibrary.GetColorBlendPosition(area.Height, new int[] { 0, 1, 3, 9, -11, -6, -2, 0 });
					cbl.Colors = new Color[] { darkColor, darkColor, mediumColor, basicColor, basicColor, mediumColor, lightColor, lightColor };
					lgb.InterpolationColors = cbl;
					return lgb;
			}
			// default:
			return lgb;
		}
		/// <summary>
		/// Vygeneruje Brush pro element grafu, typu Link, podle konstantní logiky, s proměnným zadáním barev a modifikátorů
		/// </summary>
		/// <param name="area">Prostor, pro který se má gradient vypočítat. 
		/// Gradient může být prostorově závislý (pak musí svoji prostorovou závislost vyplnit do out parametru repeatType).</param>
		/// <param name="color">Základní barva, je daná skinem pro daný vizuální typ položky, odvozeno z Aps.DataElementCls.ElementVisualType</param>
		/// <param name="gradientType">Typ gradientu = odpovídá modifikaci palety = aktuální stav elementu (běžný, pod myší, fixní, aktivně pohybovaný, selectovaný)</param>
		/// <param name="repeatType">Out informace o prostorové závislosti gradientu. Pokud bude gradient příště použit pro odpovídající prostor, nebude se opakovaně generovat.</param>
		/// <returns>Brush pro danou situaci</returns>
		private Brush _PaletteCreateBrushElementGraphLink(Rectangle area, Color color, _GraphElementGradientType gradientType, out GraphicsPaletteBrushRepeatType repeatType)
		{
			repeatType = GraphicsPaletteBrushRepeatType.Horizontal;
			Color basicColor = color;        // Základní barva, střed objektu
			Color lightColor = basicColor;   // Světlejší barva, většinou bývá nahoře (kromě stavu _GraphElementGradientType.ActiveItemBack)
			Color darkColor = basicColor;    // Tmavší barva, většinou je dole
			Color mediumColor;
			Color edgeColor = basicColor;    // Přechodová barva, jen v ActiveItemBack gradientu

			LinearGradientBrush lgb;
			ColorBlend cbl;
			HatchBrush htb;
			switch (gradientType)
			{
				case _GraphElementGradientType.Standard:
					// Standardní gradient
					lightColor = ComponentLibrary.ColorShift(basicColor, 48);
					darkColor = ComponentLibrary.ColorShift(basicColor, -64);
					return new LinearGradientBrush(area, lightColor, darkColor, 90F);
				case _GraphElementGradientType.Fixed:
					// Conservative gradient
					repeatType = GraphicsPaletteBrushRepeatType.None;
					basicColor = ComponentLibrary.ColorShift(color, +64);
					darkColor = ComponentLibrary.ColorShift(color, -32);
					htb = new HatchBrush(HatchStyle.SmallCheckerBoard, basicColor, darkColor);
					return htb;
				case _GraphElementGradientType.OnMouse:
					// OnMouse gradient
					lightColor = ComponentLibrary.ColorShift(basicColor, 80);
					darkColor = ComponentLibrary.ColorShift(basicColor, -32, 0, -32);
					return new LinearGradientBrush(area, lightColor, darkColor, 90F);
				case _GraphElementGradientType.Selected:
					// Selected gradient
					lightColor = ComponentLibrary.ColorShift(basicColor, 32, 96, 32);
					darkColor = ComponentLibrary.ColorShift(basicColor, -32, 0, -32);
					lgb = new LinearGradientBrush(area, lightColor, darkColor, 90F);
					lgb.SetSigmaBellShape(0.667F);
					return lgb;

					repeatType = GraphicsPaletteBrushRepeatType.None;
					basicColor = ComponentLibrary.ColorShift(color, +96);
					darkColor = ComponentLibrary.ColorShift(color, +16);
					htb = new HatchBrush(HatchStyle.DarkHorizontal, basicColor, darkColor);
					return htb;
				case _GraphElementGradientType.Active:
					// Aktivní gradient: má opačné pořadí barev (nahoře tmavý, dole světlý), čímž reprezentuje "dolů promáčknutý" stav:
					darkColor = ComponentLibrary.ColorShift(basicColor, -32);
					lightColor = ComponentLibrary.ColorShift(basicColor, 64);
					return new LinearGradientBrush(area, darkColor, lightColor, 90F);
			}
			// default:
			darkColor = ComponentLibrary.ColorShift(basicColor, -48);
			lightColor = ComponentLibrary.ColorShift(basicColor, 64);
			return new LinearGradientBrush(area, lightColor, darkColor, 90F);
		}
		/// <summary>
		/// Modifikace gradientů pro tvorbu Brush pro kreslení GraphElement.
		/// Brushe pro tento objekt jsou generovány obdobnou technikou v metodě this._PaletteCreateBrushElementGraphGantt(...),
		/// posloupnost barev se může lišit podle stavu objektu, a je specifikována touto hodnotou.
		/// </summary>
		private enum _GraphElementGradientType
		{
			/// <summary>Standardní gradient, pohyblivé elementy (hodnota = 0, nic se nepřičítá)</summary>
			Standard = 0,
			/// <summary>Standardní gradient, nepohyblivé elementy</summary>
			Fixed,
			/// <summary>Gradient za situace, kdy je nad elementem myš - a nic nedělá, jen číhá...</summary>
			OnMouse,
			/// <summary>Gradient za situace, kdy je element zmáčknut myší a mění se jeho pozice nebo šířka</summary>
			Active,
			/// <summary>Gradient za situace, kdy je element vybrán</summary>
			Selected
		}
		#endregion
		#region KONVERTORY VIZUÁLNÍCH TYPŮ NA POLOŽKY PALETY
		/// <summary>
		/// Druh grafiky, kterou bude zobrazen aktuální prvek v grafu Gantt ve standardním stavu.
		/// Zajistí konverzi vizuálního stylu z datové položky na odpovídající typ základního nástroje palety.
		/// </summary>
		internal static GridGraphCls.GridGraphPaletteType GetElementPaletteGantt(GraphElementVisualType visualType)
		{
			switch (visualType)
			{
				case GraphElementVisualType.Type1:
					return GridGraphCls.GridGraphPaletteType.GraphGantt1_Standard;
				case GraphElementVisualType.Type2:
					return GridGraphCls.GridGraphPaletteType.GraphGantt2_Standard;
				case GraphElementVisualType.Type3:
					return GridGraphCls.GridGraphPaletteType.GraphGantt3_Standard;
				case GraphElementVisualType.Type4:
					return GridGraphCls.GridGraphPaletteType.GraphGantt4_Standard;
				case GraphElementVisualType.Type5:
					return GridGraphCls.GridGraphPaletteType.GraphGantt5_Standard;
				case GraphElementVisualType.Type6:
					return GridGraphCls.GridGraphPaletteType.GraphGantt6_Standard;
				case GraphElementVisualType.Type7:
					return GridGraphCls.GridGraphPaletteType.GraphGantt7_Standard;
				case GraphElementVisualType.Type8:
					return GridGraphCls.GridGraphPaletteType.GraphGantt8_Standard;
				case GraphElementVisualType.Type9:
					return GridGraphCls.GridGraphPaletteType.GraphGantt9_Standard;
			}
			return GridGraphCls.GridGraphPaletteType.GraphGantt1_Standard;
		}
		/// <summary>
		/// Druh grafiky, kterou bude zobrazen aktuální prvek v grafu TaskCapacityLink ve standardním stavu.
		/// Zajistí konverzi vizuálního stylu z datové položky na odpovídající typ základního nástroje palety.
		/// </summary>
		internal static GridGraphCls.GridGraphPaletteType GetElementPaletteTaskLink(GraphElementVisualType visualType)
		{
			switch (visualType)
			{
				case GraphElementVisualType.Type1:
					return GridGraphCls.GridGraphPaletteType.GraphLink1_Standard;
				case GraphElementVisualType.Type2:
					return GridGraphCls.GridGraphPaletteType.GraphLink2_Standard;
				case GraphElementVisualType.Type3:
					return GridGraphCls.GridGraphPaletteType.GraphLink3_Standard;
				case GraphElementVisualType.Type4:
					return GridGraphCls.GridGraphPaletteType.GraphLink4_Standard;
				case GraphElementVisualType.Type5:
					return GridGraphCls.GridGraphPaletteType.GraphLink5_Standard;
				case GraphElementVisualType.Type6:
					return GridGraphCls.GridGraphPaletteType.GraphLink6_Standard;
				case GraphElementVisualType.Type7:
					return GridGraphCls.GridGraphPaletteType.GraphLink7_Standard;
				case GraphElementVisualType.Type8:
					return GridGraphCls.GridGraphPaletteType.GraphLink8_Standard;
				case GraphElementVisualType.Type9:
					return GridGraphCls.GridGraphPaletteType.GraphLink9_Standard;
			}
			return GridGraphCls.GridGraphPaletteType.GraphLink1_Standard;
		}
		/// <summary>
		/// Druh grafiky, kterou bude zobrazen aktuální prvek v grafu CapacityUtilization.
		/// Jde o prostor časového políčka grafu, tj. barva pozadí políčka.
		/// Políčko je vidět celé, pokud není vykresleno čerpání stavu kapacit (nekreslí se nebo == 0).
		/// Poznámka: čerpání stavů kapacit (sloupcový graf, kteslený přes stav kapacit) nemá svoji paletu, 
		/// jeho barva se řídí procentem čerpání.
		/// </summary>
		internal static GridGraphCls.GridGraphPaletteType GetElementPaletteCapacity(GraphElementVisualType visualType)
		{
			switch (visualType)
			{
				case GraphElementVisualType.Type1:
					return GridGraphCls.GridGraphPaletteType.CapacityFrame1;
				case GraphElementVisualType.Type2:
					return GridGraphCls.GridGraphPaletteType.CapacityFrame2;
				case GraphElementVisualType.Type3:
					return GridGraphCls.GridGraphPaletteType.CapacityFrame3;
				case GraphElementVisualType.Type4:
					return GridGraphCls.GridGraphPaletteType.CapacityFrame4;
				case GraphElementVisualType.Type5:
					return GridGraphCls.GridGraphPaletteType.CapacityFrame5;
				case GraphElementVisualType.Type6:
					return GridGraphCls.GridGraphPaletteType.CapacityFrame6;
				case GraphElementVisualType.Type7:
					return GridGraphCls.GridGraphPaletteType.CapacityFrame7;
				case GraphElementVisualType.Type8:
					return GridGraphCls.GridGraphPaletteType.CapacityFrame8;
				case GraphElementVisualType.Type9:
					return GridGraphCls.GridGraphPaletteType.CapacityFrame9;
			}
			return GridGraphCls.GridGraphPaletteType.GraphGantt1_Standard;
		}
		#endregion
		// Ke zrušení, konec.

		#region KRESLENÍ NA ZÁKLADĚ DAT PŘIPRAVENÝCH PAINTEREM IGraphElementPainter
		/// <summary>
		/// Dodatkové vykreslení elementu poté, kdy jeho kreslení zahájil painter.
		/// Tato metoda fyzicky vylreslí to, co painter nadeklaroval (data + požadavek na vykreslení).
		/// </summary>
		/// <param name="args"></param>
		private void _PaintElementDefault(GraphElementPainterArgs args)
		{
			// Spodní rámeček:
			if (args.OuterLineRunSystem)
				this._PaintElementDefaultLineOuter(args);

			// Painter chce vykreslit background:
			if (args.BackGroundRunSystem)
				this._PaintElementDefaultFillBack(args);

			// Painter chce orámovat celý prostor Background:
			if (args.BackLineRunSystem)
				this._PaintElementDefaultLineBack(args);
			// Painter chce orámovat vlevo a vpravo prostor Background:
			if (args.BackSideRunSystem)
				this._PaintElementDefaultLineSide(args);

			// Painter chce vykreslit pozadí Utilization:
			if (args.UtilizationRunSystem)
				this._PaintElementDefaultUtilization(args);

			// Painter chce vykreslit vnitřní tvary:
			if (args.InnerShapeRunSystem)
				this._PaintElementDefaultInnerShape(args);

			// Painter chce vykreslit linku TopLine (linkový graf nahoře):
			if (args.TopLineRunSystem)
				this._PaintElementDefaultTopLine(args);

			// Painter chce vykreslit obrazec FillRatio:

			// Painter chce vypsat text do elementu:
			if (args.CaptionRunSystem)
				this._PaintElementDefaultDrawCaption(args);

            // Painter chce vykreslit Image:
            if (args.PaintImage != null)
                this._PaintElementDefaultDrawImage(args);
		}
		/// <summary>
		/// Vykreslí spodní orámování pozadí elementu
		/// </summary>
		/// <param name="args"></param>
		private void _PaintElementDefaultLineOuter(GraphElementPainterArgs args)
		{
			Pen backPen = args.OuterLinePen;
			bool backPenDispose = args.OuterLinePenDispose;
			if (backPen == null && !args.OuterLineColor.IsEmpty)
			{
				this._ColorFixedPen.Color = args.OuterLineColor;
				this._ColorFixedPen.Width = (args.OuterLineWidth > 0F ? args.OuterLineWidth : 1F);
				backPen = this._ColorFixedPen;
				backPenDispose = false;
			}
			if (backPen == null)
			{
				backPen = this._PaintElementDefaultBackPen(args);
				backPenDispose = false;
			}
			if (backPen == null) return;

			if (args.BackGroundPolygon != null)
			{
				SmoothingMode osm = args.PaintArgs.Graphics.SmoothingMode;
				args.PaintArgs.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
				args.PaintArgs.Graphics.DrawPolygon(backPen, args.BackGroundPolygon);
				args.PaintArgs.Graphics.SmoothingMode = osm;
			}
			else
			{
				Rectangle backR = args.BackGroundRectangle;
				if (backR.IsEmpty)
					backR = args.DefaultDetailAreaBack;
				args.PaintArgs.Graphics.DrawRectangle(backPen, backR);
			}

			if (backPenDispose)
				backPen.Dispose();
			backPen = null;
		}
		/// <summary>
		/// Vyplní pozadí elementu.
		/// </summary>
		/// <param name="args"></param>
		private void _PaintElementDefaultFillBack(GraphElementPainterArgs args)
		{
			Brush backBrush = args.BackGroundBrush;
			bool backBrushDispose = args.BackGroundBrushDispose;
			if (backBrush == null && !args.BackGroundColor.IsEmpty)
			{
				this._ColorSolidBrush.Color = args.BackGroundColor;
				backBrush = this._ColorSolidBrush;
				backBrushDispose = false;
			}
			if (backBrush == null)
			{
				backBrush = this._PaintElementDefaultBackBrush(args);
				backBrushDispose = false;
			}
			if (backBrush == null) return;

			if (args.BackGroundPolygon != null)
			{
				args.PaintArgs.Graphics.FillPolygon(backBrush, args.BackGroundPolygon);
			}
			else
			{
				Rectangle backR = args.BackGroundRectangle;
				if (backR.IsEmpty)
					backR = args.DefaultDetailAreaBack;
				args.PaintArgs.Graphics.FillRectangle(backBrush, backR);
			}

			if (backBrushDispose)
				backBrush.Dispose();
			backBrush = null;
		}
		/// <summary>
		/// Orámuje pozadí elementu
		/// </summary>
		/// <param name="args"></param>
		private void _PaintElementDefaultLineBack(GraphElementPainterArgs args)
		{
			bool isDrawed = false;
			if (args.BackGroundPolygonLineA != null)
			{
				this._PaintElementDefaultLineBackA(args);
				isDrawed = true;
			}
			if (args.BackGroundPolygonLineB != null)
			{
				this._PaintElementDefaultLineBackB(args);
				isDrawed = true;
			}
			if (!isDrawed)
				this._PaintElementDefaultLineBackS(args);
		}
		/// <summary>
		/// Vykreslí linky okolo pozadí args.BackGroundPolygonLineA
		/// </summary>
		/// <param name="args"></param>
		private void _PaintElementDefaultLineBackA(GraphElementPainterArgs args)
		{
			if (args.BackGroundPolygonLineA != null)
			{
				bool penDispose;
				Pen linePen = this._PaintElementGetPen(args.BackLinePenA, args.BackLinePenADispose, args.BackLineAColor, args.BackLineAWidth, out penDispose);
				if (linePen == null) return;

				SmoothingMode osm = args.PaintArgs.Graphics.SmoothingMode;
				args.PaintArgs.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
				args.PaintArgs.Graphics.DrawLines(linePen, args.BackGroundPolygonLineA);
				args.PaintArgs.Graphics.SmoothingMode = osm;
			}
		}
		/// <summary>
		/// Vykreslí linky okolo pozadí args.BackGroundPolygonLineB
		/// </summary>
		/// <param name="args"></param>
		private void _PaintElementDefaultLineBackB(GraphElementPainterArgs args)
		{
			if (args.BackGroundPolygonLineB != null)
			{
				bool penDispose;
				Pen linePen = this._PaintElementGetPen(args.BackLinePenB, args.BackLinePenBDispose, args.BackLineBColor, args.BackLineBWidth, out penDispose);
				if (linePen == null) return;

				SmoothingMode osm = args.PaintArgs.Graphics.SmoothingMode;
				args.PaintArgs.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
				args.PaintArgs.Graphics.DrawLines(linePen, args.BackGroundPolygonLineB);
				args.PaintArgs.Graphics.SmoothingMode = osm;
			}
		}
		/// <summary>
		/// Vykreslí linky okolo pozadí args.BackGroundPolygon nebo args.BackGroundRectangle
		/// </summary>
		/// <param name="args"></param>
		private void _PaintElementDefaultLineBackS(GraphElementPainterArgs args)
		{
			bool penDispose;
			Pen linePen = _PaintElementGetPen(args.BackLinePen, args.BackLinePenDispose, args.BackLineColor, args.BackLineWidth, out penDispose);
			if (linePen == null) return;

			if (args.BackGroundPolygon != null)
			{
				SmoothingMode osm = args.PaintArgs.Graphics.SmoothingMode;
				args.PaintArgs.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
				args.PaintArgs.Graphics.DrawPolygon(linePen, args.BackGroundPolygon);
				args.PaintArgs.Graphics.SmoothingMode = osm;
			}
			else
			{
				Rectangle backR = args.BackGroundRectangle;
				if (backR.IsEmpty)
					backR = args.DefaultDetailAreaBack;
				args.PaintArgs.Graphics.DrawRectangle(linePen, backR);
			}

			if (penDispose)
				linePen.Dispose();
			linePen = null;
		}
		/// <summary>
		/// Orámuje vlevo a vpravo prostor background. Nemůže vycházet z polygonu.
		/// </summary>
		/// <param name="args"></param>
		private void _PaintElementDefaultLineSide(GraphElementPainterArgs args)
		{
			Rectangle backR = args.BackGroundRectangle;
			if (backR.IsEmpty)
				backR = args.DefaultDetailAreaBack;
			if (backR.Width >= args.BackSideMinElementWidth)
			{
				Pen sidePen = _PaintElementGetPen(args.BackSidePenColor, args.BackSidePenWidth);
				if (sidePen != null)
				{
					Rectangle rowGraphArea = args.RowGraphArea;
					if (backR.X >= rowGraphArea.X && backR.X < rowGraphArea.Right)
						args.PaintArgs.Graphics.DrawLine(sidePen, backR.X, backR.Y, backR.X, backR.Bottom - 1);
					if (backR.Right >= rowGraphArea.X && backR.Right < rowGraphArea.Right)
						args.PaintArgs.Graphics.DrawLine(sidePen, backR.Right - args.BackSidePenWidth + 1, backR.Y, backR.Right - args.BackSidePenWidth + 1, backR.Bottom - 1);
				}
			}
		}
		/// <summary>
		/// Vykreslí pozadí Utilization
		/// </summary>
		/// <param name="args"></param>
		private void _PaintElementDefaultUtilization(GraphElementPainterArgs args)
		{
			Brush utilBrush = args.UtilizationBrush;
			bool utilBrushDispose = args.UtilizationBrushDispose;
			if (utilBrush == null && !args.UtilizationColor.IsEmpty)
			{
				this._ColorSolidBrush.Color = args.UtilizationColor;
				utilBrush = this._ColorSolidBrush;
				utilBrushDispose = false;
			}
			if (utilBrush == null)
			{
				this._ColorSolidBrush.Color = this._ColorBlending.GetColor(args.GraphElement.DataElement.UtilizationRatio);
				utilBrush = this._ColorSolidBrush;
				utilBrushDispose = false;
			}
			if (utilBrush == null) return;

			if (args.UtilizationPolygon != null)
			{
				args.PaintArgs.Graphics.FillPolygon(utilBrush, args.UtilizationPolygon);
			}
			else
			{
				Rectangle backR = args.UtilizationRectangle;
				if (backR.IsEmpty)
					backR = args.DefaultDetailAreaElement;
				args.PaintArgs.Graphics.FillRectangle(utilBrush, backR);
			}

			if (utilBrushDispose)
				utilBrush.Dispose();
			utilBrush = null;			
		}
		/// <summary>
		/// Vykreslí vnitřní tvary, definované v args
		/// </summary>
		/// <param name="args"></param>
		private void _PaintElementDefaultInnerShape(GraphElementPainterArgs args)
		{
			foreach (GraphElementPainterArgs.InnerShapeCls innerShape in args.InnerShapeList)
			{
				if (innerShape.InnerRectangle.IsEmpty && innerShape.InnerPolygon == null)
					continue;

				if (!innerShape.InnerBackColor.IsEmpty)
				{
					this._ColorSolidBrush.Color = innerShape.InnerBackColor;
					if (!innerShape.InnerRectangle.IsEmpty)
						args.PaintArgs.Graphics.FillRectangle(this._ColorSolidBrush, innerShape.InnerRectangle);
					else if (innerShape.InnerPolygon != null)
						args.PaintArgs.Graphics.FillPolygon(this._ColorSolidBrush, innerShape.InnerPolygon);
				}

				if (!innerShape.InnerLineColor.IsEmpty)
				{
					this._ColorFixedPen.Color = innerShape.InnerLineColor;
					if (!innerShape.InnerRectangle.IsEmpty)
						args.PaintArgs.Graphics.DrawRectangle(this._ColorFixedPen, innerShape.InnerRectangle);
					else if (innerShape.InnerPolygon != null)
						args.PaintArgs.Graphics.DrawPolygon(this._ColorFixedPen, innerShape.InnerPolygon);
				}
			}
		}
		/// <summary>
		/// Vykreslí linku na horním okraji grafu, vyjadřuje poměrné čerpání kapacity, nebo vývoj zásoby
		/// </summary>
		/// <param name="args"></param>
		private void _PaintElementDefaultTopLine(GraphElementPainterArgs args)
		{
			if (args.TopLinePolygon == null) return;

			Pen linePen = _PaintElementGetPen(Color.Yellow, 2F);

			// args.PaintArgs.Graphics.DrawPolygon(this._ColorFixedPen, args.TopLinePolygon);
			args.PaintArgs.Graphics.DrawLines(linePen, args.TopLinePolygon);
		}
		/// <summary>
		/// Vykreslí text elementu.
		/// </summary>
		private void _PaintElementDefaultDrawCaption(GraphElementPainterArgs args)
		{
			if (args.GraphElement == null || args.DetailArea.IsEmpty || args.DetailArea.Width < 10) return;   // Pod 10px šířky nekreslíme.

			// Font:
			Font font = args.CaptionFont;
			bool fontDispose = args.CaptionFontDispose;
            if (font == null)
            {   // Parametry z konfigurace textů:
                font = args.GraphElement.FontForElement;
                fontDispose = false;
            }
			if (font == null)
			{   // Implicitní z palety:
				font = this._PaletteGraph.Font(GridGraphPaletteType.ElementCaptionText);
				fontDispose = false;
			}
			if (font == null) return;

			// Štětec, barva:
			Brush brush = args.CaptionBrush;
			bool brushDispose = args.CaptionBrushDispose;
            if (brush == null)
            {
                brush = args.GraphElement.FontBrushForElement;
                brushDispose = false;
            }
			if (brush == null && !args.CaptionColor.IsEmpty)
			{
				this._ColorSolidBrush.Color = args.CaptionColor;
				brush = this._ColorSolidBrush;
				brushDispose = false;
			}
			if (brush == null)
			{
				brush = this._PaletteGraph.Brush(GridGraphPaletteType.ElementCaptionText, Rectangle.Empty);
				brushDispose = false;
			}
			if (brush == null) return;

			// Vlastní text:
			Rectangle captionArea = args.DefaultCaptionArea;
			string text = args.CaptionText;                // Explicitní text popisku, určený painterem
			if (String.IsNullOrEmpty(text))
			{	// Text zkusím získat z elementu:
				// Počet znaků, které můžeme zobrazit, řádek s elementem, získat text Caption:
				float sizeWidth = 0.96f * ((float)captionArea.Width - 6f);          // Šířka v pixelech, do které jsem ochoten kreslit Caption
				float charCount = sizeWidth / args.PaintArgs.Graphics.MeasureString("1234567890", font).Width * 10F;
				text = args.GraphElement.GetCaptionForLength(args.RowItem, charCount, t => (args.PaintArgs.Graphics.MeasureString(t, font).Width / sizeWidth));
				
				// text = args.GetElementCaption(charCount);                // Voláme aplikační metodu, která určí text
			}
			if (String.IsNullOrEmpty(text)) return;

			// Psaní textu:
			this._PaintText(args.PaintArgs.Graphics, text, font, brush, captionArea, TextFormatFlags.HorizontalCenter);
		}
        /// <summary>
        /// Vykreslí Image
        /// </summary>
        /// <param name="args"></param>
        private void _PaintElementDefaultDrawImage(GraphElementPainterArgs args)
        {
            Point pivot = args.BackGroundRectangle.Location;
            pivot.Y += args.BackGroundRectangle.Height / 2;
            Size imageSize = args.PaintImage.Size;
            Rectangle imageArea = pivot.GetRectangleFFromCenter(imageSize);
            args.PaintArgs.Graphics.DrawImage(args.PaintImage, imageArea);

            // Zvětšit VisualRectangle (=interaktivní prostor) tak, aby pokrýval i Image:
            int x = (imageArea.X < args.VisualRectangle.X ? imageArea.X : args.VisualRectangle.X);
            int r = (imageArea.Right > args.VisualRectangle.Right ? imageArea.Right : args.VisualRectangle.Right);
            if (x != args.VisualRectangle.X || r != args.VisualRectangle.Right)
                args.VisualRectangle = new Rectangle(x, args.VisualRectangle.Y, (r - x), args.VisualRectangle.Height);
        }
		/// <summary>
		/// Vrací defaultní barvu pro výplň pozadí elementu
		/// </summary>
		/// <param name="args"></param>
		/// <returns></returns>
		private Brush _PaintElementDefaultBackBrush(GraphElementPainterArgs args)
		{
			if (args.GraphElement.DataElement.ElementLayer == GraphElementLayerType.TempLayer)
				return this._PaletteGraph.Brush(GridGraphPaletteType.TempElement, args.BrushArea);

			GraphElementPaletteItem paletteItem = args.GetPaletteItemForColor(args.ElementBackColor);
			return this._PaletteElements.Brush(paletteItem, args.BrushArea);
		}
		/// <summary>
		/// Vrátí pero podle daných atributů
		/// </summary>
		/// <param name="penColor">Barva pera, použije se pokud není předáno vstupní pero explicitPen. Pokud bude Color.Empty, použije se systémová barva (černá).</param>
		/// <param name="penWidth">Šířka pera, použije se pokud není předáno vstupní pero explicitPen. Default = 1</param>
		/// Pokud bude použito vstupní pero explicitPen, bude sem nastavena hodnota toDispose, jinak bude false.</param>
		/// <returns></returns>
		private Pen _PaintElementGetPen(Color penColor, float penWidth)
		{
			bool penDispose;
			return _PaintElementGetPen(null, false, penColor, penWidth, out penDispose);
		}
		/// <summary>
		/// Vrátí pero podle daných atributů
		/// </summary>
		/// <param name="explicitPen">Vstupní pero, může být null</param>
		/// <param name="toDispose">Požadavek, aby vstupní pero (explicitPen) bylo po použití zlikvidováno (Dispose)</param>
		/// <param name="penColor">Barva pera, použije se pokud není předáno vstupní pero explicitPen. Pokud bude Color.Empty, použije se systémová barva (černá).</param>
		/// <param name="penWidth">Šířka pera, použije se pokud není předáno vstupní pero explicitPen. Default = 1</param>
		/// <param name="penDispose">Out: vrácené pero se má zlikvidovat (Dispose).
		/// Pokud bude použito vstupní pero explicitPen, bude sem nastavena hodnota toDispose, jinak bude false.</param>
		/// <returns></returns>
		private Pen _PaintElementGetPen(Pen explicitPen, bool toDispose, Color penColor, float penWidth, out bool penDispose)
		{
			penDispose = false;
			if (explicitPen != null)
			{
				penDispose = toDispose;
				return explicitPen;
			}

			this._ColorFixedPen.Color = (penColor.IsEmpty ? Color.Black : penColor);
			this._ColorFixedPen.Width = (penWidth > 0F ? penWidth : 1F);
			return this._ColorFixedPen;
		}
		/// <summary>
		/// Vrátí defaultní pero pro orámování pozadí elementu
		/// </summary>
		/// <param name="args"></param>
		/// <returns></returns>
		private Pen _PaintElementDefaultBackPen(GraphElementPainterArgs args)
		{
			return this._PaletteGraph.Pen(GridGraphPaletteType.GraphGantt3_Active);
		}
		/// <summary>
		/// Vrátí příznak stavu elementu, který ovlivní režim zobrazování elementu.
		/// </summary>
		/// <param name="element">Element, jehož modifikaci určujeme.</param>
		/// <returns>Typ palety pro vykreslení elementu.</returns>
		private GraphElementState _ElementDetectState(GraphElementDataCls element)
		{
			if (element == null) return GraphElementState.Dead;

			GID elementGId = element.DataElement.GId;
			bool isDead = element.IsDead;
			bool isPinned = element.IsPinned || element.IsBlocking;
			bool isSelected = (this._SelectedInfo.IsGidSelected(elementGId));
			bool isOnMouse = (elementGId == this._MouseCurrentTarget.ElementGId);
			bool isActive = (elementGId == this._MouseDownStateTarget.ElementGId && ((this._MouseCurrentAction & _MouseActionType.GraphActiveAll) > 0));
			bool isInEditor = (this._EditedElementTable.ContainsKey(elementGId));

			if (isDead)
				// Element nelze posouvat ani resizovat:
				return GraphElementState.Dead;
			if (!isPinned)
			{	// Element není připíchnutý k scheduli:
				if (isActive)
					// Elementem se aktivně pohybuje:
					return GraphElementState.ActiveFree;
				else if (isSelected)
					// Element je Selected:
					return GraphElementState.SelectedFree;
				else if (isInEditor)
					// Element je v editoru:
					return GraphElementState.InEditorFree;
				else if (isOnMouse)
					// Element se nyní nachází pod myší:
					return GraphElementState.OnMouseFree;
				return GraphElementState.Standart;
			}
			else
			{	// Element je připíchnutý k scheduli:
				if (isActive)
					// Elementem se aktivně pohybuje:
					return GraphElementState.ActivePinned;
				else if (isSelected)
					// Element je Selected:
					return GraphElementState.SelectedPinned;
				else if (isInEditor)
					// Element je v editoru:
					return GraphElementState.InEditorPinned;
				else if (isOnMouse)
					// Element se nyní nachází pod myší:
					return GraphElementState.OnMousePinned;
				return GraphElementState.Pinned;
			}
		}
		/// <summary>
		/// Zjistí, zda je element aktivní (tj. zda je selectovaný), volitelně detekuje stav, zda je element "pod myší".
		/// </summary>
		/// <param name="element"></param>
		/// <returns></returns>
		private bool _ElementDetectActive(GraphElementDataCls element, bool detectOnMouse)
		{
			if (element == null) return false;

			GID elementGId = element.DataElement.GId;
			bool isSelected = (this._SelectedInfo.IsGidSelected(elementGId));
			bool isOnMouse = (elementGId == this._MouseCurrentTarget.ElementGId);
			bool isActive = (elementGId == this._MouseDownStateTarget.ElementGId && ((this._MouseCurrentAction & _MouseActionType.GraphActiveAll) > 0));
			return (isSelected || (detectOnMouse && isOnMouse) || isActive);
		}
		#endregion
		#region SPOLUPRÁCE S GENERÁTOREM GRAFICKÝCH NÁSTROJŮ PRO KRESLENÍ ELEMENTŮ S VYUŽITÍM SLUŽBY IGraphElementPalette
		/// <summary>
		/// Vygeneruje pero pro kreslení čáry v rámci daného elementu
		/// </summary>
		/// <param name="paletteItem">Specifikace položky palety</param>
		/// <returns></returns>
		internal virtual Pen ElementPaletteCreatePen(GraphElementPaletteItem paletteItem)
		{
			Pen pen = null;
			GraphElementPaletteArgs args = new GraphElementPaletteArgs(paletteItem, Rectangle.Empty, this._PaletteElements);
			IGraphElementPalette paletteService = this._GetPaletteService();
			if (paletteService != null)
				pen = paletteService.GetPen(args);

			if (pen == null)
				pen = new Pen(Color.Black, 1F);

			return pen;
		}
		/// <summary>
		/// Vygeneruje štětec pro vybarvení elementu
		/// </summary>
		/// <param name="paletteItem">Specifikace položky palety</param>
		/// <returns></returns>
		internal virtual Brush ElementPaletteCreateBrush(GraphElementPaletteItem paletteItem, Rectangle rectangle, out GraphicsPaletteBrushRepeatType repeatType)
		{
			repeatType = GraphicsPaletteBrushRepeatType.None;
			Brush brush = null;
			GraphElementPaletteArgs args = new GraphElementPaletteArgs(paletteItem, rectangle, this._PaletteElements);
			IGraphElementPalette paletteService = this._GetPaletteService();

			if (paletteService != null)
				brush = paletteService.GetBrush(args, rectangle, out repeatType);

			if (brush == null)
				brush = new SolidBrush(Color.Blue);

			return brush;
		}
		/// <summary>
		/// Vygeneruje font pro psaní do elementu
		/// </summary>
		/// <param name="paletteItem"></param>
		/// <returns></returns>
		internal virtual Font ElementPaletteCreateFont(GraphElementPaletteItem paletteItem)
		{
			Font font = null;
			GraphElementPaletteArgs args = new GraphElementPaletteArgs(paletteItem, Rectangle.Empty, this._PaletteElements);
			IGraphElementPalette paletteService = this._GetPaletteService();

			if (paletteService != null)
				font = paletteService.GetFont(args);

			if (font == null)
				font = new Font(SystemFonts.DefaultFont, FontStyle.Regular);

			return font;
		}
		/// <summary>
		/// Vygeneruje obrázek pro kreslení do elementu
		/// </summary>
		/// <param name="paletteItem"></param>
		/// <returns></returns>
		internal virtual Image ElementPaletteCreateImage(GraphElementPaletteItem paletteItem)
		{
			Image image = null;
			GraphElementPaletteArgs args = new GraphElementPaletteArgs(paletteItem, Rectangle.Empty, this._PaletteElements);
			IGraphElementPalette paletteService = this._GetPaletteService();

			if (paletteService != null)
				image = paletteService.GetImage(args);

			return image;
		}
		/// <summary>
		/// Vrátí aktuálního poskytovatele služby IGraphElementPalette, případně ho vyhledá. Pokud neexistuje, vrací null.
		/// </summary>
		/// <param name="paletteItem"></param>
		/// <returns></returns>
		private IGraphElementPalette _GetPaletteService()
		{
			if (!this._ElementPaletteScanned)
				this._DetectBestPaletteService();
			return this._ElementPaletteProvider;
		}
		/// <summary>
		/// Pro aktuální graf určí nejvhodnější generátor palety
		/// </summary>
		/// <param name="paletteItem"></param>
		private void _DetectBestPaletteService()
		{
			// Klíč aktuálního grafu z hlediska vhodnosti generátoru palety:
			GraphElementPaletteKey paletteKey = new GraphElementPaletteKey(this._GridData.DefaultGraphType, this._GridData.FirstGIdToLoad.ClassNumber);
			IGraphElementPalette bestPalette = null;
			float bestRatio = 0F;

			lock (this._ElementPaletteLocker)
			{
				// Ze systému získám seznam generátorů palety, které jsou k dispozici:
				IEnumerable<IGraphElementPalette> palettes = Steward.GetServiceObjectList<IGraphElementPalette>(true);

				foreach (IGraphElementPalette palette in palettes)
				{
					// Zeptáme se postupně každého poskytovatele služby IGraphElementPalette, jak rád by generoval paletu pro náš graf:
					float thisRatio = palette.GetPriority(paletteKey);
					if (bestRatio == 0F || thisRatio > bestRatio) // Chce kreslit, a víc než všechny dřívější?
					{
						bestPalette = palette;
						bestRatio = thisRatio;
					}
				}
			}
			this._ElementPaletteScanned = true;
			this._ElementPaletteProvider = bestPalette;
		}
		/// <summary>
		/// Nalezený provider typu IGraphElementPalette = generátor dat palety pro elementy
		/// </summary>
		private IGraphElementPalette _ElementPaletteProvider = null;
		/// <summary>
		/// Příznak, že vyhledání generátoru dat palety pro elementy již proběhlo
		/// </summary>
		private bool _ElementPaletteScanned = false;
		/// <summary>
		/// Zámek pro vyhledání generátoru palety
		/// </summary>
		private object _ElementPaletteLocker = new object();
		#endregion
	}
}
